﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Surface.Presentation.Controls;
using MapSurface.UIModelElement;
using System.Windows;
using System.Windows.Controls;
using System.Reflection;

namespace MapSurface.WidgetSurface
{
    public class EditModeElement : ScatterViewItem
    {
        #region EditModeElement Properties
        private MapSurface.UIModelElement.UIElement _uiElement;

        public MapSurface.UIModelElement.UIElement UiElement
        {
            get { return _uiElement; }
            set { _uiElement = value; }
        }

        private Object _widgetInstance;

        public Object WidgetInstance
        {
            get { return _widgetInstance; }
            set { _widgetInstance = value; }
        }
        private Thickness _defaultMargin = new Thickness(3);

        public Thickness DefaultMargin
        {
            get { return _defaultMargin; }
            set { _defaultMargin = value; }
        }
        private Double _minHeight= Double.Parse("50");
        private Double _minWidth = Double.Parse("50");

        private string _defaultContainerStyle = "";

        public string DefaultContainerStyle
        {
            get { return _defaultContainerStyle; }
            set { _defaultContainerStyle = value; }
        }
     
        
        #endregion
        
        public EditModeElement( MapSurface.UIModelElement.UIElement element, Object instance)
        {
            this._uiElement = element;
            this._widgetInstance = instance;
            this.MinHeight = _minWidth;
            this.MinHeight = _minHeight;
            this.Content=instance;
            this.BorderThickness = _defaultMargin;
            //AddChild(instance);
            //Content = instance;
         }

     }
    public class EditModeContainer : ScatterView
    {
        #region EditModeContainer Properties
        private MapSurface.UIModelElement.UIElement _uiElement;
        private AssemblyReflexion.AssemblyReflexion _assembly;

        public MapSurface.UIModelElement.UIElement UiElement
        {
            get { return _uiElement; }
            set { _uiElement = value; }
        }

        private Object _widgetInstance;

        public Object WidgetInstance
        {
            get { return _widgetInstance; }
            set { _widgetInstance = value; }
        }
        private Thickness _defaultMargin = new Thickness(10);

        public Thickness DefaultMargin
        {
            get { return _defaultMargin; }
            set { _defaultMargin = value; }
        }
        private Double _minHeight = Double.Parse("50");
        private Double _minWidth = Double.Parse("50");

        private string _defaultContainerStyle = "";

        public string DefaultContainerStyle
        {
            get { return _defaultContainerStyle; }
            set { _defaultContainerStyle = value; }
        }

        #endregion

        public EditModeContainer(MapSurface.UIModelElement.UIElement element, Object instance)
        {
            {
                _assembly= new AssemblyReflexion.AssemblyReflexion(@"..\..\Assembly\", null);
                this._uiElement = element;
                this._widgetInstance = instance;
                try{
                    this.MinHeight = Double.Parse( _assembly.getAttribute(instance,"Height").ToString() );
                    this.MinWidth = Double.Parse(_assembly.getAttribute(instance, "Width").ToString()); ;
                }catch (Exception )
                {
                    this.MinHeight = 50;
                    this.MinWidth = 50;
                }
                this.BorderThickness = _defaultMargin;
                new Managers().addChild(instance, this);
                // ((System.Windows.UIElement)instance)

            }
        }
    }
    class Managers
    {
        public Object addChild(Object objectUI, Object obj)
        {
            if (obj != null)
                if (objectUI != null)
                {
                    if (isItemControl(objectUI))
                        ((ItemsControl)objectUI).Items.Add(obj);
                    else if (isPanel(objectUI))
                        ((Panel)objectUI).Children.Add((System.Windows.UIElement)obj);
                    else if (isContentControl(objectUI))
                        ((ContentControl)objectUI).Content = obj;
                    else if (hasChild(objectUI))
                        setVisualChild(objectUI, obj);
                }
                else
                    objectUI = obj;
            return objectUI;
        }
        public Boolean isItemControl(Object element)
        {
            try
            {

                ItemsControl obj = (ItemsControl)element;
                return true;
            }
            catch (InvalidCastException e)
            {
#if DEBUG
                Console.Out.WriteLine("[DEBUG] isItemControl " + e.Message);
#endif


            }
            return false;
        }
        public Boolean isPanel(Object element)
        {
            try
            {
                Panel p = (Panel)element;
                return true;
            }
            catch (InvalidCastException e)
            {
#if DEBUG
                Console.Out.WriteLine("[DEBUG] isPanel " + e.Message);
#endif


            }
            return false;
        }
        public Boolean isContentControl(Object element)
        {
            try
            {
                ContentControl c = (ContentControl)element;
                return true;
            }
            catch (InvalidCastException e)
            {
#if DEBUG
                Console.Out.WriteLine("[DEBUG] isContentControl " + e.Message);
#endif
            }
            return false;
        }
        public Boolean hasChild(Object element)
        {
            try
            {
                Type t = element.GetType();
                System.Reflection.MethodInfo mi = t.GetMethod("GetVisualChild", BindingFlags.Instance | BindingFlags.NonPublic);
                if (mi != null)
                    return true;
            }
            catch (Exception e)
            {
#if DEBUG
                Console.Out.WriteLine("[DEBUG] hasChild " + e.Message);
#endif

            }
            return false;

        }
        public void setVisualChild(Object element, Object child)
        {
            if (hasChild(element))
            {
                try
                {
                    setProperty(element.GetType(), "Child", child, element);

                }
                catch (Exception e)
                {
                    Type t = element.GetType();
                    System.Reflection.MethodInfo mi = t.GetMethod("AddVisualChild", BindingFlags.Instance | BindingFlags.NonPublic);
                    Object[] param = { child };
                    if (mi != null)
                        mi.Invoke(element, param);
#if DEBUG
                    Console.Out.WriteLine("[DEBUG] setVisualChild " + e.Message);
#endif
                }
            }

        }
        private Object setProperty(Type type, String name, Object value, Object instance)
        {
            PropertyInfo pi = type.GetProperty(name);
            if (pi != null)
                pi.SetValue(instance, value, null);
#if DEBUG
            Console.WriteLine("[DEBUG] setproperty name={0} value={1} at {2} object ", name, value.ToString(), instance.ToString());
#endif
            return instance;
        }

 
    }
}
